﻿using System;
using System.Linq;
using System.Web;
using CodeGenerationPipeline.Contracts;
using System.IO;
using AbstraX.Contracts;
using System.Collections;
using System.Collections.Generic;
using Metaspec;
using AbstraX.Bindings;
using AbstraX;
using AbstraX.BuildEvents;
using AbstraX.Contracts.CodeParsers;
using Utils;
using AbstraX.ServerInterfaces;

namespace SolutionFramework.Web
{
    public class FeedbackBuildFilter : IBuildFilter
    {
        private IDomainHostApplication host;
        private IEventsService eventsService;
        private List<IPipelineStep> steps;
        private string fileRoot;

        public FeedbackBuildFilter(IDomainHostApplication host, string fileRoot)
        {
            this.host = host;
            this.Enabled = true;
            this.fileRoot = fileRoot;

            eventsService = host.EventsService;
        }

        public string Name
        {
            get 
            {
                return "Feedback Filter";
            }
        }

        public bool Enabled { get; set; }

        public void OnGenerationStarted()
        {
            eventsService.PostMessage(new EventMessage(Message.GenerationStarted));
        }

        public void OnGenerationComplete()
        {
            eventsService.PostMessage(new EventMessage(Message.GenerationCompleted));
        }

        public void OnBuildGeneralError(Exception ex, string stackTrace)
        {
            eventsService.PostMessage(new EventMessage(Message.GeneralError, ex, stackTrace));
        }

        public void OnBuildFatalError(Exception ex, string stackTrace)
        {
            eventsService.PostMessage(new EventMessage(Message.FatalError, ex, stackTrace));
        }

        public void OnBuildGeneralError(Exception ex)
        {
            eventsService.PostMessage(new EventMessage(Message.GeneralError, ex));
        }

        public void OnBuildFatalError(Exception ex)
        {
            eventsService.PostMessage(new EventMessage(Message.FatalError, ex));
        }

        public void OnGenerateFrom(List<IBindingsTree> bindings, out bool abortGeneration)
        {
            abortGeneration = false;
        }

        public void OnStepsAdded(List<IPipelineStep> steps)
        {
        }

        public void OnStepPreGenerate(IPipelineStep step, Dictionary<string, IElementBuild> builds, DirectoryInfo workspaceDirectory, out bool skipStep, out bool abortGeneration)
        {
            skipStep = false;
            abortGeneration = false;
        }

        public void OnStepPreGenerate(IPipelineStep step, ICodeGenerationPackage incomingPackage, out bool skipStep, out bool abortGeneration)
        {
            skipStep = false;
            abortGeneration = false;
        }

        public void OnStepPostGenerate(IPipelineStep step, ICodeGenerationPackage outgoingPackage)
        {
        }

        public void OnOutput(object sender, BuildMessageEventArgs eventArgs)
        {
        }

        public void OnGeneratorFileWithBuildPreBuild(IGenerator generator, ref Type generatorType, ref IElementBuild build, ref FileInfo fileInfo, ref string _namespace, ref Dictionary<string, object> extraValues, out bool skipBuildFile, out bool abortStep)
        {
            skipBuildFile = false;
            abortStep = false;

            eventsService.PostMessage(new EventMessage(Message.FileGenerationStarted, fileInfo.Name));
        }

        public void OnGeneratorFileWithListPreBuild(IGenerator generator, ref Type generatorType, ref FileInfo fileInfo, ref string _namespace, ref IEnumerable list, out bool skipBuildFile, out bool abortStep)
        {
            skipBuildFile = false;
            abortStep = false;

            eventsService.PostMessage(new EventMessage(Message.FileGenerationStarted, fileInfo.Name));
        }

        public void OnFileGenerated(string fileName)
        {
            eventsService.PostMessage(new EventMessage(Message.FileGenerationCompleted, fileName.RemoveStart(fileRoot)));
        }

        public void OnStepSkipped(IPipelineStep step)
        {
        }

        public void OnGenerationAborted()
        {
        }

        public void OnStepAborted(IGenerator generator, IPipelineStep lastStep, FileInfo lastFileInfo)
        {
        }

        public void OnStepAborted(IGenerator generator, IPipelineStep lastStep)
        {
        }

        public void OnBuildFileSkipped(IGenerator generator, IPipelineStep lastStep, FileInfo fileInfo)
        {
        }

        public void OnBindingsBuild(List<IBindingsTree> bindings, ref IBindingsBuilder builder)
        {
            var count = bindings.GetNodeCount();

            eventsService.PostMessage(new EventMessage(Message.GeneralMessage, string.Format("Creating build objects from bindings. Count={0}", count)));
        }

        public void OnGenerationAbort()
        {
        }

        public void OnGeneratorFileWithListCodeWriter(IGenerator generator, FileInfo fileInfo, string _namespace, IEnumerable list, ref ICodeWriter codeWriter)
        {
        }

        public void OnGeneratorFileWithBuildCodeWriter(IGenerator generator, IElementBuild build, FileInfo fileInfo, string _namespace, Dictionary<string, object> extraValues, ref ICodeWriter codeWriter)
        {
        }

        public void OnGeneratorFileWithBuildPostBuild(IGenerator generator, IElementBuild build, ref FileInfo fileInfo, string _namespace, Dictionary<string, object> extraValues, ICodeParser codeParser, ref string output)
        {
        }

        public void OnGeneratorFileWithListPostBuild(IGenerator generator, ref FileInfo fileInfo, string _namespace, IEnumerable list, ICodeParser codeParser, ref string output)
        {
        }
    }
}